#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <qextserialenumerator.h>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->bdSkyPlot->setPrefix("BD");
    ui->gpsSkyPlot->setPrefix("GPS");

    gps = new QGpsParser(this);
    connect(gps, SIGNAL(positionChanged(double,char,double,char,float,QByteArray,QByteArray)),
            this, SLOT(onPositionChanged(double,char,double,char,float,QByteArray,QByteArray)));
    connect(gps, SIGNAL(utcTimeChanged(QDateTime)),
            this, SLOT(onUtcTimeChanged(QDateTime)));
    connect(gps, SIGNAL(speedChanged(float,float,float)),
            this, SLOT(onSpeedChanged(float,float,float)));
    connect(gps, SIGNAL(BeiDouSatellites(QList<SatelliteInfo>)),
            this, SLOT(onBeiDouSatellites(QList<SatelliteInfo>)));
    connect(gps, SIGNAL(GPSSatellites(QList<SatelliteInfo>)),
            this, SLOT(onGPSSatellites(QList<SatelliteInfo>)));

    loadCommPorts();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::loadCommPorts()
{
    ui->commPortList->clear();
#ifndef _WIN32
    ui->commPortList->addItem("UART0", "/dev/s3c2410_serial0");
    ui->commPortList->addItem("UART1", "/dev/s3c2410_serial1");
    ui->commPortList->addItem("UART2", "/dev/s3c2410_serial2");
    ui->commPortList->addItem("UART3", "/dev/s3c2410_serial3");
#endif
    QList<QextPortInfo> ports = QextSerialEnumerator::getPorts();
    for(int i = 0; i < ports.count(); i++)
    {
        const QextPortInfo &p = ports.at(i);
        //qDebug()<<p.portName<<p.physName<<p.friendName<<p.enumName<<p.vendorID<<p.productID;
#ifdef _WIN32
        if(p.portName.contains("COM"))
        {
            ui->commPortList->addItem(p.friendName, p.portName);
        }
#else
        if(!p.friendName.isEmpty())
        {
            ui->commPortList->addItem(p.friendName, "/dev/" + p.portName);
        }
#endif
    }
}

#ifndef _WIN32
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#endif
void MainWindow::on_openCommPortBtn_clicked()
{
    if(gps->isValid())
        return;
#ifndef _WIN32
    int fd = ::open("/dev/gpJ4", O_RDWR);
    ::ioctl(fd, 0x01, 0);                           // set GPJ4_0 output
    ::ioctl(fd, 0x10, 0);                           // GPJ4_0 output low level
    ::usleep(300000);
    ::ioctl(fd, 0x11, 1);                           // GPJ4_0 output high level
    ::close(fd);
#endif
    gps->start(ui->commPortList->itemData(
                   ui->commPortList->currentIndex()
                   ).toString()
               );
    if(gps->isValid())
    {
        ui->openCommPortBtn->setEnabled(false);
        ui->closeCommPortBtn->setEnabled(true);
    }
    else
        on_closeCommPortBtn_clicked();
}

void MainWindow::on_closeCommPortBtn_clicked()
{
    gps->stop();
    ui->openCommPortBtn->setEnabled(true);
    ui->closeCommPortBtn->setEnabled(false);
}

void MainWindow::onPositionChanged(double latitude, char nsFlag,
                                   double longitude, char ewFlag,
                                   float altitude,
                                   const QByteArray &rawLatitude,
                                   const QByteArray &rawLongitude)
{
    ui->positionEdit->setText(
                QString("%1%2,%3%4 %5 %6 %7")
                .arg(longitude, 0, 'f').arg(ewFlag)
                .arg(latitude, 0, 'f').arg(nsFlag).arg(altitude)
                .arg(QString(rawLongitude)).arg(QString(rawLatitude)));
}

void MainWindow::onUtcTimeChanged(const QDateTime &utcTime)
{
    ui->timeEdit->setText(utcTime.toString("yyyy-MM-dd hh:mm:ss"));
}

void MainWindow::onSpeedChanged(float speed, float speedKMH, float dir)
{
    ui->directionEdit->setText(
                QString("%1 Not, %2 km/h, %3N")
                .arg(speed).arg(speedKMH).arg(dir));
}

void MainWindow::onBeiDouSatellites(const QList<SatelliteInfo> &sats)
{
    ui->bdSkyPlot->setSatellites(sats);
}

void MainWindow::onGPSSatellites(const QList<SatelliteInfo> &sats)
{
    ui->gpsSkyPlot->setSatellites(sats);
}
